from django.core.exceptions import ValidationError
from django.http import JsonResponse
from django.shortcuts import render, redirect
from web import models
from django import forms
from utils.BootStrapForm import BootStrapForm
from utils.encrypt import md5
from django.urls import reverse
from utils.response import BaseResponse
from utils.pager import Pagination
from django.db.models import Q
from utils.link import filter_reverse
from django.db import transaction


def customer_list(request):
    keyword = request.GET.get('keyword', "").strip()
    # print(keyword)
    con = Q()
    if keyword:
        con.connector = 'OR'
        con.children.append(('username__contains', keyword))
        con.children.append(('mobile__contains', keyword))
        con.children.append(('level__title__contains', keyword))

    # 所有的数据，主动跨表
    query_set = models.Customer.objects.filter(con).filter(active=1).select_related('level', 'creator')

    pagination = Pagination(request, query_set)

    context = {
        # [0:10] 切片
        'queryset': pagination.queryset(),
        'page_string': pagination.html(),
        'keyword': keyword,
    }
    return render(request, 'customer_list.html', context)


class CustomerModelForm(BootStrapForm, forms.ModelForm):
    exclude_fields_list = ['level']

    confirm_password = forms.CharField(
        label="重复密码",
        widget=forms.PasswordInput(render_value=True)
    )

    class Meta:
        model = models.Customer
        fields = ['username', 'mobile', 'password', 'confirm_password', 'level']
        widgets = {
            'password': forms.PasswordInput(render_value=True),
            'level': forms.RadioSelect(attrs={'class': 'form-radio'}),
        }

    def clean_password(self):
        password = self.cleaned_data['password']
        return md5(password)

    def clean_confirm_password(self):
        password = self.cleaned_data['password']
        confirm_password = md5(self.cleaned_data['confirm_password'])
        if password != confirm_password:
            raise ValidationError("密码不一致")
        return confirm_password

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # 后续可能会用到 request
        self.fields['level'].queryset = models.Level.objects.filter(active=1)


def customer_add(request):
    """添加用户"""
    if request.method == 'GET':
        form = CustomerModelForm(request)
        return render(request, 'form2.html', {'form': form})

    form = CustomerModelForm(request, data=request.POST)
    if not form.is_valid():
        return render(request, 'form2.html', {'form': form})

    form.instance.creator_id = request.wl_user.id
    form.save()
    return redirect(reverse('customer_list'))


class CustomerModelEditForm(BootStrapForm, forms.ModelForm):
    class Meta:
        model = models.Customer
        fields = ['username', 'mobile', 'level']

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # 后续可能会用到 request
        self.fields['level'].queryset = models.Level.objects.filter(active=1)


def customer_edit(request, pk):
    """编辑用户"""
    customer_instance = models.Customer.objects.get(id=pk, active=1)
    if request.method == 'GET':
        form = CustomerModelEditForm(request, instance=customer_instance)
        return render(request, 'form.html', {'form': form})
    form = CustomerModelEditForm(request, data=request.POST, instance=customer_instance)
    if not form.is_valid():
        return render(request, 'form.html', {'form': form})
    form.save()

    # 实现跳转
    return redirect(filter_reverse(request, '/customer/list/'))
    # # 获取 _filter 参数
    # filter_sting = request.GET.get('_filter', '')
    # if not filter_sting:
    #     return redirect(reverse('customer_list'))
    # return redirect(f'/customer/list/?{filter_sting}')


class CustomerModelResetForm(BootStrapForm, forms.ModelForm):
    confirm_password = forms.CharField(
        label="重复密码",
        widget=forms.PasswordInput(render_value=True)
    )

    class Meta:
        model = models.Customer
        fields = ['username', 'password', 'confirm_password']
        widgets = {
            'password': forms.PasswordInput(render_value=True),
            'username': forms.TextInput(attrs={'readonly': 'readonly'}),
        }

    def clean_password(self):
        password = self.cleaned_data['password']
        return md5(password)

    def clean_confirm_password(self):
        password = self.cleaned_data['password']
        confirm_password = md5(self.cleaned_data['confirm_password'])
        if password != confirm_password:
            raise ValidationError("密码不一致")
        return confirm_password


def customer_reset(request, pk):
    """重置密码"""
    customer_instance = models.Customer.objects.get(id=pk, active=1)
    if request.method == 'GET':
        username = customer_instance.username
        # 表单默认显示需要重置密码的用户名，提高用户体验 initial={'username': username}
        form = CustomerModelResetForm(initial={'username': username})
        return render(request, 'form.html', {'form': form})
    form = CustomerModelResetForm(instance=customer_instance, data=request.POST)
    if not form.is_valid():
        return render(request, 'form.html', {'form': form})
    form.save()
    return redirect(reverse("customer_list"))


def customer_delete(request):
    cid = request.GET.get('cid', 0)
    if not cid:
        res = BaseResponse(status=False, detail="请选择要删除的数据!")
        return JsonResponse(res.dict)

    exists = models.Customer.objects.filter(id=cid, active=1).exists()
    if not exists:
        res = BaseResponse(status=False, detail="数据不存在!")
        return JsonResponse(res.dict)

    models.Customer.objects.filter(id=cid, active=1).update(active=0)
    res = BaseResponse(status=True)
    return JsonResponse(res.dict)


class ChargeModelForm(BootStrapForm, forms.ModelForm):
    # charge_type = forms.ChoiceField(
    #     label='类型',
    #     choices=[(1, "充值"), (2, "扣款")]
    # )

    class Meta:
        model = models.TransationRecord
        fields = ['charge_type', 'amount']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['charge_type'].choices = [(1, "充值"), (2, "扣款")]


def customer_charge(request, pk):
    """交易记录"""
    queryset = models.TransationRecord.objects.filter(customer_id=pk, customer__active=1, active=1).select_related('customer').order_by('-id')
    pager = Pagination(request, queryset)
    form = ChargeModelForm()
    # return render(request, 'customer_charge.html', locals())

    return render(request, 'customer_charge.html', {'pager': pager, 'form': form, 'pk': pk})


def customer_charge_add(request, pk):
    form = ChargeModelForm(data=request.POST)
    if not form.is_valid():
        return JsonResponse({'status': False, 'detail': form.errors})

    # 校验成功
    amount = form.cleaned_data['amount']
    charge_type = form.cleaned_data['charge_type']

    try:
        # 原子操作，只有数据库操作都成功才生效，否则回滚
        with transaction.atomic():
            # 1.对当前登录的用户进行更新操作 + 锁(排他锁、需要结合事务一起使用)
            customer_obj = models.Customer.objects.filter(id=pk, active=1).select_for_update().first()
            if charge_type == 1:
                customer_obj.balance += amount
            else:
                if customer_obj.balance < amount:
                    return JsonResponse(({'status': False, 'detail': {"amount": ["余额不足！"]}}))
                else:
                    customer_obj.balance -= amount
            customer_obj.save()

            # 2.生成交易记录
            form.instance.customer = customer_obj
            form.instance.creator_id = request.wl_user.id
            form.save()

            return JsonResponse({'status': True})

    except Exception as e:
        return JsonResponse(({'status': False, 'detail': {"amount": ["操作失败！"]}}))
